package interfaces.hud.pilot.status;

import logic.common.player.Player;
import logic.common.player.playerListeners.HunterChangedEvent;
import logic.common.player.playerListeners.KillAssistEvent;
import logic.common.player.playerListeners.KillEvent;
import logic.common.player.playerListeners.MissionAssistEvent;
import logic.common.player.playerListeners.PlayerListener;
import logic.common.player.playerListeners.RespawnEvent;
import logic.common.player.playerListeners.TargetChangedEvent;
import logic.ships.hunter.Hunter;
import logic.status.StatusChangedEvent;
import logic.status.StatusListener;
import fileHandling.language.properties.NodeProps;
import interfaces.PropertyContent;
import interfaces.hud.BasicHUD;
import interfaces.hud.spectate.SpectateChangeEvent;
import interfaces.hud.spectate.SpectateListener;
import interfaces.hud.spectate.SpectateWidget;
import interfaces.superWidgets.InterfaceWindow;

import networking.messages.syncMessages.ValueType;

import org.fenggui.layout.StaticLayout;
import org.fenggui.util.Color;

public class HunterStatusHUD extends InterfaceWindow implements SpectateWidget {
	
	private Hunter hunter;
	private PropertyContent hpContent, shieldContent, energyContent, speedContent;
	private int border, widgetHeight, widgetWidth, hpY, shieldY, energyY, speedY;
	private StatusListener statusListener;
	private BasicHUD hud;
	
	public HunterStatusHUD(BasicHUD hud) {
		super(false, "");
		this.hud = hud;
		
		content.setLayoutManager(new StaticLayout());
		
		setXY(hud.getWidth() / 2 - hud.getWidth() / 6, 0);
		setSize(hud.getWidth() / 3, hud.getHeight() / 9);
		
		border = getHeight() / 12;
		widgetHeight = getHeight() / 5;
		widgetWidth = getWidth() - 3 * border;
		
		speedY = border;
		hpY = speedY + widgetHeight;
		shieldY = hpY + widgetHeight;
		energyY = shieldY + widgetHeight;
		
		init();
		createListener();
		
		Player player = hud.getIngameState().getPlayer();
		addPlayerListener(player);
		if(player.getHunter() != null) setHunter(player.getHunter());
		
		layout();
	}
	
	private void addPlayerListener(final Player player) {
		hud.addListener(player, new PlayerListener() {
			@Override
			public void respawned(RespawnEvent event) {
				setHunter(player.getHunter());
			}

			@Override
			public void hunterChanged(HunterChangedEvent event) {}
			@Override
			public void targetChanged(TargetChangedEvent event) {}
			@Override
			public void killed(KillEvent event) {}
			@Override
			public void killAssist(KillAssistEvent event) {}
			@Override
			public void missionAssist(MissionAssistEvent event) {}
		});
	}
	
	private void init() {
		PropertyContent.Mode mode = PropertyContent.Mode.LEFT;
		
		energyContent = new PropertyContent(widgetWidth, widgetHeight, border, energyY, NodeProps.Energy, mode);
		setupPropertyContent(energyContent, Color.LIGHT_BLUE);
		
		shieldContent = new PropertyContent(widgetWidth, widgetHeight, border, shieldY, NodeProps.Shields, mode);
		setupPropertyContent(shieldContent, Color.BLUE);
		
		hpContent = new PropertyContent(widgetWidth, widgetHeight, border, hpY, NodeProps.Hitpoints, mode);
		setupPropertyContent(hpContent, Color.RED);
		
		speedContent = new PropertyContent(widgetWidth, widgetHeight, border, speedY, NodeProps.Speed, mode);
		setupPropertyContent(speedContent, Color.LIGHT_BLUE);
	}
	
	private void setupPropertyContent(PropertyContent widget, Color color) {
		widget.changeBackgroundColor(Color.BLACK);
		widget.changeValueColor(color);
		content.addWidget(widget);
	}
	
	private void createListener() {
		statusListener = new StatusListener() {
			@Override
			public void valueChanged(StatusChangedEvent event) {
				ValueType type = event.getType();
				switch(type) {
					case HP: hpContent.setValue(event.getIntValue()); break;
					case Shield: shieldContent.setValue(event.getIntValue()); break;
					case Energy: energyContent.setValue(event.getIntValue()); break;
					case Speed: speedContent.setValue(event.getFloatValue()); break;
				}
			}
		};
	}
	
	private void addListeners() {
		assert(hunter != null);
		hud.addListener(hunter, statusListener);
		
		hpContent.setMaxValue(hunter.getMaxHP());
		shieldContent.setMaxValue(hunter.getMaxShield());
		energyContent.setMaxValue(hunter.getMaxEnergy());
		speedContent.setMaxValue(hunter.getMaxBoostSpeed());
		
		hpContent.setValue(hunter.getCurrentHP());
		shieldContent.setValue(hunter.getCurrentShield());
		energyContent.setValue(hunter.getCurrentEnergy());
		speedContent.setValue(hunter.getCurrentEngineSpeed());
	}
	
	private void removeListeners() {
		assert(hunter != null);
		hunter.removeStatusListener(statusListener);
	}
	
	private void setHunter(Hunter hunter) {
		if(this.hunter == hunter) return;
		if(this.hunter != null) removeListeners();
		this.hunter = hunter;
		if(this.hunter != null) addListeners();
	}

	@Override
	public SpectateListener getSpectateListener() {
		return new SpectateListener() {
			@Override
			public void spectating(SpectateChangeEvent event) {
				setHunter(event.getWatchedPlayer().getHunter());
			}
		};
	}
}